import router from "@/router"
import { isEmpty } from "@/utils"
import type { LocationQueryRaw, RouteLocationNormalized, RouteLocationNormalizedLoaded, RouteMeta } from "vue-router"

export type RouteTag = {
    fullPath: string
    path: string
    name: string
    hash: string
    meta: RouteMeta
    params: object
    query?: LocationQueryRaw
    cacheName?: string
}

/**
 * 路由
 */
export const useRouteStore = defineStore("route", () => {
    // 标签页
    const tabs = ref<RouteTag[]>([])
    // 缓存页面
    const cachedViews = ref<string[]>([])

    /**
     * 构造 RouteTag 对象
     */
    const buildRouteTag = (route: RouteLocationNormalizedLoaded): RouteTag => {
        const { fullPath, hash, meta, name, params, path, query } = route
        const tag: RouteTag = { name: name as string, path, fullPath, hash, meta, params, query }
        if (meta.noCache === true) {
            tag.cacheName = undefined
        } else {
            tag.cacheName = route.name as string
        }
        return tag
    }

    /**
     * 判断是否当前路由
     */
    const isCurrentTab = (tag: RouteTag, currentRoute: RouteLocationNormalizedLoaded) => {
        return tag.fullPath === currentRoute.fullPath
    }

    /**
     * 是否固定标签页
     */
    const isAffixTab = (tag: RouteTag) => {
        return tag.meta.affix === true
    }

    /**
     * 返回指定标签的位置
     */
    const indexTab = (tag: RouteTag) => {
        return tabs.value.findIndex(item => item.fullPath == tag.fullPath)
    }

    /**
     * 菜单属性
     */
    const attrTab = (tag: RouteTag) => {
        const attr: Recordable<boolean> = {
            canClose: true,
            canCloseLeft: true,
            canCloseRight: true,
            canCloseOthers: true,
            canCloseAll: true
        }
        if (tabs.value.length <= 1) {
            Object.keys(attr).forEach(key => (attr[key] = false))
            return attr
        }
        const index = indexTab(tag)
        if (index < 0) {
            Object.keys(attr).forEach(key => (attr[key] = false))
            return attr
        }
        if (isAffixTab(tag)) {
            attr.canClose = false
        }
        if (index === 0) {
            attr.canCloseLeft = false
        }
        if (index >= tabs.value.length - 1) {
            attr.canCloseRight = false
        }
        return attr
    }

    /**
     * 根据当前路由新建标签页，缓存由 router 守卫进行添加
     */
    const addTab = (route: RouteLocationNormalizedLoaded) => {
        const exist = tabs.value.some(item => item.fullPath === route.fullPath)
        !exist && tabs.value.push(buildRouteTag(route))
    }

    /**
     * 关闭菜单
     */
    const closeTab = (tag: RouteTag, currentRoute: RouteLocationNormalizedLoaded) => {
        // 固定标签页不能关闭
        if (isAffixTab(tag)) {
            return
        }
        // 保证至少一个标签页
        if (tabs.value.length <= 1) {
            return
        }
        // 获取标签位置
        const index = indexTab(tag)
        if (index < 0) {
            return
        }
        // 删除缓存视图
        removeCachedView(tag.cacheName)
        // 删除标签页
        tabs.value.splice(index, 1)
        // 当前路由被关闭，路由到下一个标签页
        if (isCurrentTab(tag, currentRoute)) {
            const tab = index >= tabs.value.length ? tabs.value[tabs.value.length - 1] : tabs.value[index]
            routeTag(tab)
        }
    }

    /**
     * 关闭左侧菜单
     */
    const closeLeftTabs = (tag: RouteTag, currentRoute: RouteLocationNormalizedLoaded) => {
        // 保证至少一个标签页
        if (tabs.value.length <= 1) {
            return
        }
        // 获取标签位置
        const index = indexTab(tag)
        if (index < 0) {
            return
        }
        let currentClosed = false
        tabs.value = tabs.value.filter((item, i) => {
            if (i >= index || isAffixTab(item)) {
                return true
            }
            removeCachedView(item.cacheName)
            if (isCurrentTab(item, currentRoute)) {
                currentClosed = true
            }
            return false
        })
        if (currentClosed) {
            routeTag(tag)
        }
    }

    /**
     * 关闭右侧菜单
     */
    const closeRightTabs = (tag: RouteTag, currentRoute: RouteLocationNormalizedLoaded) => {
        // 保证至少一个标签页
        if (tabs.value.length <= 1) {
            return
        }
        // 获取标签位置
        const index = indexTab(tag)
        if (index < 0) {
            return
        }
        let currentClosed = false
        tabs.value = tabs.value.filter((item, i) => {
            if (i <= index || isAffixTab(item)) {
                return true
            }
            removeCachedView(item.cacheName)
            if (isCurrentTab(item, currentRoute)) {
                currentClosed = true
            }
            return false
        })
        if (currentClosed) {
            routeTag(tag)
        }
    }

    /**
     * 关闭其它菜单
     */
    const closeOtherTabs = (tag: RouteTag, currentRoute: RouteLocationNormalizedLoaded) => {
        console.log(tag)

        // 保证至少一个标签页
        if (tabs.value.length <= 1) {
            return
        }
        console.log(tag)
        // 获取标签位置
        const index = indexTab(tag)
        if (index < 0) {
            return
        }
        console.log(index)
        let currentClosed = false
        tabs.value = tabs.value.filter((item, i) => {
            if (i === index || isAffixTab(item)) {
                return true
            }
            removeCachedView(item.cacheName)
            if (isCurrentTab(item, currentRoute)) {
                currentClosed = true
            }
            return false
        })
        if (currentClosed) {
            routeTag(tag)
        }
    }

    /**
     * 关闭全部菜单
     */
    const closeAllTabs = (currentRoute: RouteLocationNormalizedLoaded) => {
        // 保证至少一个标签页
        if (tabs.value.length <= 1) {
            return
        }
        tabs.value = tabs.value.filter(item => isAffixTab(item))
        // 如果没有固定标签页，保留当前标签页
        if (isEmpty(tabs.value)) {
            addTab(currentRoute)
        }
        let currentExist = false
        let cachedNames: string[] = []
        tabs.value.forEach(item => {
            if (isCurrentTab(item, currentRoute)) {
                currentExist = true
            }
            if (item.cacheName) {
                cachedNames.push(item.cacheName)
            }
        })
        cachedViews.value = cachedNames
        // 当前标签页被关闭，导航到第一个固定标签页
        if (!currentExist) {
            routeTag(tabs.value[0])
        }
    }

    /**
     * 导航到指定标签
     */
    const routeTag = (tab: RouteTag) => {
        router.push({ path: tab.path, query: tab.query })
    }

    /**
     * 路由添加缓存
     */
    const addCacheView = (route: RouteLocationNormalized) => {
        const name = route.meta.noCache === true ? undefined : (route.name as string)
        if (isEmpty(name)) {
            return
        }
        const cachedName = name as string
        if (!cachedViews.value.includes(cachedName)) {
            cachedViews.value.push(cachedName)
        }
    }

    const removeCachedView = (name?: string) => {
        if (isEmpty(name)) {
            return
        }
        const index = cachedViews.value.findIndex(v => v === name)
        if (index >= 0) {
            cachedViews.value.splice(index, 1)
        }
    }

    const removeCachedRoute = (route: RouteLocationNormalizedLoaded) => {
        const name = route.meta.noCache === true ? undefined : (route.name as string)
        if (isEmpty(name)) {
            return
        }
        removeCachedView(name)
    }

    /**
     * 清理
     */
    const clear = () => {
        tabs.value = []
        cachedViews.value = []
    }

    return {
        tabs,
        cachedViews,
        attrTab,
        addTab,
        closeTab,
        closeLeftTabs,
        closeRightTabs,
        closeOtherTabs,
        closeAllTabs,
        isCurrentTab,
        isAffixTab,
        addCacheView,
        removeCachedRoute,
        clear
    }
})
